import React from 'react';
import './index.css'; // 引入样式文件

const ITEM_HEIGHT = 60; // 每个 item 的高度
const BUFFER_COUNT = 18;  // 缓冲区个数
const INITIAL_DATA_COUNT = 1000000; // 初始数据个数

function VirtualList() {
    const [dataList, setDataList] = React.useState<number[]>([]); // 保存数据源
    const [position, setPosition] = React.useState<[number, number]>([0, 0]); // 截取缓冲区 + 视图区索引
    const scroll = React.useRef<HTMLDivElement>(null); // 获取 scroll 元素
    const box = React.useRef<HTMLDivElement>(null); // 获取元素用于容器高度
    const context = React.useRef<HTMLDivElement>(null); // 用于移动视图区域，形成滑动效果
    const scrollInfo = React.useRef({
        height: 500, // 容器高度
        bufferCount: BUFFER_COUNT, // 缓冲区个数
        itemHeight: ITEM_HEIGHT, // 每一个 item 高度
        renderCount: 0, // 渲染区个数
    });

    React.useEffect(() => {
        const height = box.current?.offsetHeight || 0; // 获取外层容器高度
        const renderCount = Math.ceil(height / ITEM_HEIGHT) + BUFFER_COUNT; // 计算渲染区个数 27
        scrollInfo.current = { ...scrollInfo.current, renderCount, height }; // 更新 scrollInfo

        const dataList = Array.from({ length: INITIAL_DATA_COUNT }, (_, index) => index + 1); // 生成初始数据
        setDataList(dataList); // 设置数据源
        setPosition([0, renderCount]); // 设置初始位置
    }, []);

    const handleScroll = React.useCallback(() => {
        const { scrollTop } = scroll.current!;
        const { itemHeight, renderCount } = scrollInfo.current;
        const currentOffset = scrollTop - (scrollTop % itemHeight);
        const start = Math.floor(scrollTop / itemHeight);
        context.current!.style.transform = `translate3d(0, ${currentOffset}px, 0)`;
        const end = Math.floor(scrollTop / itemHeight + renderCount + 1);
        
        if (end !== position[1] || start !== position[0]) {
            setPosition([start, end]);
        }
    }, [position]);

    const { itemHeight, height } = scrollInfo.current; // 解构 scrollInfo
    const [start, end] = position; // 解构位置
    const renderList = React.useMemo(() => dataList.slice(start, end), [dataList, start, end]); // 渲染区间
    return (
        <div className="list_box" ref={box}>
            <div className="scroll_box" style={{ height: `${height}px` }} onScroll={handleScroll} ref={scroll}>
                <div className="scroll_hold" style={{ height: `${dataList.length * itemHeight}px` }} />
                <div className="context" ref={context}>
                    {renderList.map((item) => (
                        <div className="list" key={item}>
                            {item}-item
                        </div>
                    ))}
                </div>
            </div>
        </div>
    );
}

export default VirtualList; // 导出 VirtualList 组件